package paril.SlabUtilities;

import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;

public class SlabListener implements Listener
{
	@EventHandler()
	public void onBlockBreak(BlockBreakEvent event)
	{
		if (event.isCancelled())
			return;
		
		Block block = event.getBlock();
		Player player = event.getPlayer();
		World world = player.getWorld();

		if (block.getType() != Material.DOUBLE_STEP)
			return;
		
		event.setCancelled(true);
		
		CraftItemStack stack = (CraftItemStack)player.getItemInHand();
		
		byte stepData = block.getData();
		boolean brokenTop = BlockRoutines.AimingAtTopOfBlock(player, block);
		
		if (event.getPlayer().getGameMode() == GameMode.SURVIVAL && (stack.getType() == Material.WOOD_PICKAXE ||
			stack.getType() == Material.STONE_PICKAXE ||
			stack.getType() == Material.IRON_PICKAXE ||
			stack.getType() == Material.GOLD_PICKAXE ||
			stack.getType() == Material.DIAMOND_PICKAXE))
		{
			stack.getHandle().damage(1, ((CraftPlayer)player).getHandle());
			
			if (stack.getDurability() == stack.getType().getMaxDurability())
				player.setItemInHand(null);
			else
				player.setItemInHand(stack);
			
			byte itemData = BlockRoutines.SetStepUpsideDown(stepData, false);
			ItemStack slabStack = new ItemStack(Material.STEP, 1, itemData, itemData);
			
			if (brokenTop)
				world.dropItem(block.getLocation().add(0.5, 0.5, 0.5), slabStack);
			else
				world.dropItem(block.getLocation().add(0.5, 0, 0.5), slabStack);
		}
		
		while (!block.setTypeId(Material.STEP.getId()));
		block.setData(BlockRoutines.SetStepUpsideDown(stepData, !brokenTop));
	}
	
	@EventHandler()
	public void onBlockPlace(BlockPlaceEvent event)
	{
		if (event.getBlockPlaced().getType() != Material.STEP)
			return;
		
		BlockFace face = event.getBlockAgainst().getFace(event.getBlockPlaced());
		
		if (face == BlockFace.UP || face == BlockFace.DOWN)
			return;
		else if (event.getBlockAgainst().getType() == Material.STEP)
			event.getBlockPlaced().setData(BlockRoutines.GetStepUpsideDown(event.getBlockPlaced().getData(), event.getBlockAgainst().getData()));
		else
		{
			boolean clickedTop = BlockRoutines.AimingAtTopOfBlock(event.getPlayer(), event.getBlockAgainst());
			event.getBlockPlaced().setData(BlockRoutines.SetStepUpsideDown(event.getBlockPlaced().getData(), clickedTop));
		}
	}
	
	@EventHandler()
	public void onPlayerInteract(PlayerInteractEvent event)
	{
		if (event.getAction() != Action.RIGHT_CLICK_BLOCK)
			return;
		
		Player player = event.getPlayer();
		BlockFace face = event.getBlockFace();
		Block block = event.getClickedBlock();
		
		if (block == null)
			return;
		if (block.getType() == Material.STEP)
			return;
		if (block.getRelative(face).getType() != Material.STEP)
			return;
		
		if (player.getItemInHand() == null ||
			player.getItemInHand().getType() != Material.STEP)
			return;
		
		byte stepData = BlockRoutines.SetStepUpsideDown(player.getItemInHand().getData().getData(), false);
		Block stepBlock = block.getRelative(face);
		byte stepBlockData = BlockRoutines.SetStepUpsideDown(stepBlock.getData(), false);
		
		if (stepData != stepBlockData)
			return;
		
		Material oldStep = stepBlock.getType();
		byte oldData = stepBlock.getData();

		while (!stepBlock.setTypeId(Material.DOUBLE_STEP.getId()));
		stepBlock.setData(stepData);
		
		BlockPlaceEvent placeEvent = CraftEventFactory.callBlockPlaceEvent(((CraftWorld)stepBlock.getWorld()).getHandle(), ((CraftPlayer)event.getPlayer()).getHandle(), stepBlock.getState(), stepBlock.getX(), stepBlock.getY(), stepBlock.getZ());
		
		if (!placeEvent.canBuild() || placeEvent.isCancelled())
		{
			while (!stepBlock.setTypeId(oldStep.getId()));
			stepBlock.setData(oldData);
		
			return;
		}
	
		if (event.getPlayer().getGameMode() == GameMode.SURVIVAL)
		{
			ItemStack hand = player.getItemInHand();
			
			if (hand.getAmount() == 1)
				player.setItemInHand(null);
			else
			{
				hand.setAmount(hand.getAmount() - 1);
				player.setItemInHand(hand);
			}
		}
	}
}
